import sys
import time
from PyQt5.QtWidgets import QMessageBox
from GUI.calibration import Ui_Calibration_MainWindow
from PyQt5 import QtCore,QtWidgets
from PyQt5.QtGui import QImage,QPixmap
from PyQt5.QtCore import Qt
import cv2

from fatigue_algo.fatigue_detector.eye_Detector import EyeDetector_real
from service.face_utils import getlargest_face,landmarkPlot,face_plot, get_frontFace_template, frontFace_judgement
from detect_window import DetectWindow

class CalibrateWindow(QtWidgets.QMainWindow,Ui_Calibration_MainWindow):

    def __init__(self,face_detector,landmark_detector):
        super(CalibrateWindow, self).__init__()
        self.setupUi(self)  # 创建窗体对象
        self.camera = None
        self.scrfd_detector = face_detector  #人脸检测模型
        self.landmark_detector = landmark_detector   #人脸关键点检测模型
        self.cal_landmark = get_frontFace_template(self.scrfd_detector,self.landmark_detector)
        self.eye_detector = EyeDetector_real()

    #重写窗口关闭事件：关闭摄像头
    def closeEvent(self,event):
        if(self.camera != None and self.camera.isOpened()):
            cv2.destroyAllWindows()
            self.camera.release()
        super().closeEvent(event)

    #开启摄像头，并回显到qlabel上
    def open_camera(self):
        self.camera = cv2.VideoCapture(0,cv2.CAP_DSHOW)
        self.calibrate()  #正脸校准弹窗显示

        calibrate_count = 3 #检测次数
        front_face_flag = False  #正脸标志位
        temp_count = 0 # 默认检测3次
        EAR_B_list = []  #受试者B的最大睁眼EAR序列（长度为calibrate_count）
        while(self.camera.isOpened()):
            ret,frame = self.camera.read()
            if(ret):
                dets = self.scrfd_detector.detect_faces(frame)[0]

                landmarkPlot(frame, self.cal_landmark[0])  # 校准正脸的关键点
                if(len(dets) != 0):
                    det = dets[getlargest_face(dets)]
                    face_plot(frame, [det])

                    landmark = self.landmark_detector.detect_landmarks(frame,[[det]])
                    '''########################  判断人脸是否校准  #########################'''
                    # 先判断是否在正脸位置上
                    front_face_flag = frontFace_judgement(self.cal_landmark[0][0], landmark[0][0], angle_error=15)
                    if(front_face_flag):
                        landmarkPlot(frame, self.cal_landmark[0],color=(0,0,255))  # 校准正脸的关键点
                        self.label_2.setText("检测到正脸")
                        # 会判断EAR是否小于0.2，如果小于会提示"睁大眼睛"
                        EAR_B = self.eye_detector.getEAR(landmark[0][0])
                        if(EAR_B < 0.28):
                            QMessageBox.information(self, '提示', '请不要闭眼，请重新检测')
                        else:
                            print(f"EAR_B = {EAR_B}")
                            EAR_B_list.append(EAR_B)
                            temp_count += 1
                            if(calibrate_count - temp_count > 0):
                                info = f"校准成功, 还要校准 {calibrate_count - temp_count} 次"
                                QMessageBox.information(self, '提示', info)
                    else:
                        self.label_2.setText("请根据参考点摆正正脸~~")
                else:  #未检测到人脸
                    self.label_2.setText("请进行正脸校准~~")

                if(temp_count >= calibrate_count):
                    # 将EAR_B写入到根目录的文件中
                    file = open("EAR_B.txt", "w+")
                    line = ""
                    for EAR_B in EAR_B_list:
                        line += str(EAR_B) + "\n"
                    file.write(line)
                    file.close()

                    QMessageBox.information(self, '提示', '校准成功')
                    break

                '''############################  图片回显至QLabel  ############################'''
                #将图片回显值qlabel上
                height, width, bytesPerComponent = frame.shape
                bytesPerLine = 3 * width
                cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame)

                # 利用QImage加载图片到组件中
                QImg = QImage(frame.data, width, height, bytesPerLine, QImage.Format_RGB888)  # PIL image

                qImg_scaled = QImg.scaled(self.label.width(), self.label.height(), Qt.IgnoreAspectRatio,
                                          Qt.SmoothTransformation)

                pixmap = QPixmap.fromImage(qImg_scaled)
                self.label.setPixmap(pixmap)  # 利用QPixmap组件绘制图片

            key = cv2.waitKey(10)

        cv2.destroyAllWindows()
        self.camera.release()
        self.camera = None
        self.detectWindow = DetectWindow(self.scrfd_detector, self.landmark_detector)
        self.detectWindow.show()
        self.close()

    #校准正脸
    def calibrate(self):
        # 弹窗
        QMessageBox.information(self, '提示', '正在校准正脸...')



if __name__ == '__main__':
    from PyQt5 import QtCore
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)#自适应分辨率

    app = QtWidgets.QApplication(sys.argv)
    window = CalibrateWindow()
    window.show()

    sys.exit(app.exec_())